use std::sync::Arc;

use gitlab::{api::{users::{self}, AsyncQuery}, AsyncGitlab, GitlabBuilder, GitlabError, UserPublic};
use tokio::runtime::{Builder, Handle, Runtime};

use crate::models::GitlabInfo;


// 定义一个全局的 Runtime 实例
lazy_static::lazy_static! {
  static ref RUNTIME: Arc<Runtime> = {
      let rt = Builder::new_multi_thread()
          .enable_all()
          .build()
          .expect("Failed to build a new runtime");
      Arc::new(rt)
  };
}


#[tauri::command]
pub async fn add_gitlab_info(data: GitlabInfo) -> Result<GitlabInfo, String> {
  use crate::models::{insert, check};
  // 校验参数
  let check_param = data.clone();
  if check_param.host.is_none() || check_param.token.is_none()
    || check_param.host.unwrap().is_empty() || check_param.token.unwrap().is_empty() {
    return Err("参数错误".into())
  }

  // let handle = Handle::try_current().or_else(|_| RUNTIME.lock().unwrap().handle().clone());

  let rt = tokio::runtime::Runtime::new().unwrap();

  let result = create_gitlab_api(&data).await.map_err(|e| e.to_string())
  .and_then(|api|
    rt.handle().block_on(async { get_current_user(&api).await }).map_err(|e| e.to_string()))
  .and_then(|current_user| {
    rt.handle().block_on(async { check(&data).await }).or_else(|_| {
      let mut add_gitlab_info = data.clone();
      add_gitlab_info.user_id = Some(current_user.id.to_string());
      add_gitlab_info.user_name = Some(current_user.username);
      add_gitlab_info.user_email = Some(current_user.email);
      rt.handle().block_on(async { insert(&add_gitlab_info).await }).map_err(|e| e.to_string())
    })
  });
  result
  // create_gitlab_api(&data).await
  //   .map_err(|e| e.to_string())
  //   .and_then(|api|
  //     rt.block_on(get_current_user(&api)).map_err(|e| e.to_string()))
  //   .and_then(|current_user| {
  //     rt.block_on(check(&data)).or_else(|_| {
  //       let mut add_gitlab_info = data.clone();
  //       add_gitlab_info.user_id = Some(current_user.id.to_string());
  //       add_gitlab_info.user_name = Some(current_user.username);
  //       add_gitlab_info.user_email = Some(current_user.email);
  //       rt.block_on(insert(&add_gitlab_info)).map_err(|e| e.to_string())
  //     })
  //   })
  // 尝试访问
  // match create_gitlab_api(&data).await {
  //   Ok(api) => {
  //     match get_current_user(&api).await {
  //       Ok(current_user) => {
  //         match check(&data).await {
  //           // 检查通过 返回结果
  //           Ok(info) => Ok(info),
  //           Err(_) => {
  //             // 不存在创建
  //             let mut add_gitlab_info = data.clone();
  //             add_gitlab_info.user_id = Some(current_user.id.to_string());
  //             add_gitlab_info.user_name = Some(current_user.username);
  //             add_gitlab_info.user_email = Some(current_user.email);
  //             // 保存信息
  //             match insert(&add_gitlab_info).await {
  //               Ok(info) => Ok(info),
  //               Err(err) => Err(err.to_string())
  //             }
  //           }
  //         }
  //       },
  //       Err(e) => Err(e.to_string())
  //     }
  //   },
  //   Err(err) => Err(err.to_string())
  // }
}

//// 创建gitlab_api
pub async fn create_gitlab_api(gitlab_info: &GitlabInfo) -> Result<AsyncGitlab, GitlabError> {
  let info = gitlab_info.clone();
  let mut gitlab = GitlabBuilder::new(info.host.unwrap(), info.token.unwrap());
  if !info.https.unwrap() {
    gitlab.insecure();
  }
  gitlab.build_async().await
}


pub async fn get_current_user(client: &AsyncGitlab) -> Result<UserPublic, GitlabError> {
  users::CurrentUser::builder().build().unwrap().query_async(client)
    .await.map_err(|e| GitlabError::from(e))
}
